<?php

namespace App\Jobs;

use App\ExcelCheck;
use App\Excels;
use App\Imports\ExcelToMedicine;
use DB;
use Excel;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Redis;

class StandardMedicineImportHandler implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $enterprise_id = 0;
    protected $merchant_id = 0;
    protected $excel_id = 0;
    protected $excel_check_id = 0;
    public $timeout = 600;
    protected $file_path = '';
    protected $status_key_in_redis;
    /**
     * Create a new job instance.
     *
     * @param $excel_id
     * @param $enterprise_id
     * @param $merchant_id
     * @param $excel_check_id
     * @return void
     */
    public function __construct($excel_id,$enterprise_id,$merchant_id = 0,$excel_check_id = 0)
    {
        $this->excel_id         = $excel_id ? $excel_id : 0;
        $this->enterprise_id    = $enterprise_id ? $enterprise_id : 0;
        $this->merchant_id      = $merchant_id   ? $merchant_id : 0;
        $this->excel_check_id   = $excel_check_id? $excel_check_id : 0;
        $this->status_key_in_redis = 'job.xlsx.st'.$excel_check_id;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $start  = microtime(1);
        $result = $this->execute();
        $end    = microtime(1);
        $execute_time = $end - $start;
        if ($result){
            //导入完成
            \Log::notice('StandardMedicineImportHandler:execute()finishIn:'.$execute_time.' sec');
        } else {
            //导入错误
            \Log::notice('StandardMedicineImportHandler:execute()ERROR:'.$execute_time.' sec');
        }
    }

    protected function execute(){
        try{
            DB::beginTransaction();
            /** @var ExcelCheck $excelCheck */
//            $excelCheck = ExcelCheck::whereExcelId($this->excel_id)->lockForUpdate()->first();
            $excelCheck = ExcelCheck::whereId($this->excel_check_id)->lockForUpdate()->first();
            if (!$excelCheck){
                DB::rollBack();
                \Log::error('StandardMedicineImportHandler:execute()ERROR:!$excelCheck');
                return 0;
            }
//            if (!$excelCheck->allow_import){
//                DB::rollBack();
//                \Log::error('StandardMedicineImportHandler:execute()ERROR:!$excelCheck->allow_import');
//                return 0;
//            }
            if ($excelCheck->in_execution){
                DB::rollBack();
                \Log::error('StandardMedicineImportHandler:execute()ERROR:$excelCheck->in_execution');
                return 0;
            }
            if ($excelCheck->success_import){
                DB::rollBack();
                \Log::error('StandardMedicineImportHandler:execute()ERROR:$excelCheck->success_import');
                return 0;
            }
            $excelCheck->in_execution = 1;
            $excelCheck->save();
            $excel = Excels::whereId($excelCheck->excel_id)->first();
            if (!$excel){
                $excelCheck->in_execution = 0;
                if ($excelCheck->error_message){
                    $temp = json_decode($excelCheck->error_message);
                    if (is_array($temp)){
                        $message = array_merge($temp,['job'=>'严重错误：Excel表中没有这个文件，传入的excel_id为'.$excelCheck->excel_id]);
                        $excelCheck->error_message = json_encode($message);
                    } else {
                        $excelCheck->error_message = json_encode(['job'=>'严重错误：Excel表中没有这个文件，传入的excel_id为'.$excelCheck->excel_id]);
                    }

                }
                $excelCheck->save();
                DB::commit();
                \Log::error('StandardMedicineImportHandler:execute()ERROR:!$excel');
                return 0;
            }
            $this->file_path = storage_path() . '/app/excel/'.$excel->key.$excel->excel_type;
            $import_status = ['now'=>0,'total'=>$excelCheck->total_num];
            Redis::set($this->status_key_in_redis,json_encode($import_status),'EX','1800');
            $excelToMedicine = $this->import();
            $result = $excelToMedicine->getResult();
            $error_msg = $excelToMedicine->getErrorMessage();
            if (count($error_msg) == 0){
                $excelCheck->success_import = 1;
                $excelCheck->error_message = json_encode($error_msg);
            } else {
                $excelCheck->success_import = 0;
            }
            $excelCheck->import_result = $result ? json_encode($result) : null;
            $excelCheck->in_execution = 0;
            $excelCheck->save();
            DB::commit();
            return $result;

        } catch (\Exception $e) {
            \Log::error('StandardMedicineImportHandler->execute'.$e->getMessage());
            \Log::error('StandardMedicineImportHandler->execute:Trace'.$e->getTraceAsString());
            DB::rollBack();
            return 0;
        }
    }
    protected function import(){
        $excelToMedicine = new ExcelToMedicine($this->enterprise_id,$this->merchant_id,$this->excel_check_id);
        Excel::import($excelToMedicine,$this->file_path);
        return $excelToMedicine;
    }
}
